// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.iso.weather.fx;

import java.util.ArrayList;
import org.joml.Vector2i;
import org.joml.Vector3f;
import zombie.Lua.LuaManager;
import zombie.characters.IsoGameCharacter;
import zombie.characters.IsoPlayer;
import zombie.core.Color;
import zombie.core.Core;
import zombie.core.PerformanceSettings;
import zombie.core.SpriteRenderer;
import zombie.core.opengl.RenderSettings;
import zombie.core.textures.ColorInfo;
import zombie.core.textures.Texture;
import zombie.core.textures.TextureFBO;
import zombie.debug.DebugLog;
import zombie.debug.DebugOptions;
import zombie.input.GameKeyboard;
import zombie.iso.DiamondMatrixIterator;
import zombie.iso.IsoCamera;
import zombie.iso.IsoChunk;
import zombie.iso.IsoChunkMap;
import zombie.iso.IsoDirections;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoUtils;
import zombie.iso.IsoWorld;
import zombie.iso.SpriteDetails.IsoFlagType;
import zombie.iso.SpriteDetails.IsoObjectType;
import zombie.iso.areas.isoregion.IsoRegions;
import zombie.iso.areas.isoregion.regions.IWorldRegion;
import zombie.iso.areas.isoregion.regions.IsoWorldRegion;
import zombie.iso.sprite.IsoSprite;
import zombie.iso.sprite.IsoSpriteManager;
import zombie.network.GameServer;

public class WeatherFxMask {
    private static boolean DEBUG_KEYS = false;
    private static TextureFBO fboMask;
    private static TextureFBO fboParticles;
    public static IsoSprite floorSprite;
    public static IsoSprite wallNSprite;
    public static IsoSprite wallWSprite;
    public static IsoSprite wallNWSprite;
    public static IsoSprite wallSESprite;
    private static Texture texWhite;
    private static int curPlayerIndex;
    public static final int BIT_FLOOR = 0;
    public static final int BIT_WALLN = 1;
    public static final int BIT_WALLW = 2;
    public static final int BIT_IS_CUT = 4;
    public static final int BIT_CHARS = 8;
    public static final int BIT_OBJECTS = 16;
    public static final int BIT_WALL_SE = 32;
    public static final int BIT_DOOR = 64;
    public static float offsetX = (float)(32 * Core.TileScale);
    public static float offsetY = (float)(96 * Core.TileScale);
    public static ColorInfo defColorInfo = new ColorInfo();
    private static int DIAMOND_ROWS = 1000;
    public int x;
    public int y;
    public int z;
    public int flags;
    public IsoGridSquare gs;
    public boolean enabled;
    private static WeatherFxMask.PlayerFxMask[] playerMasks = new WeatherFxMask.PlayerFxMask[4];
    private static DiamondMatrixIterator dmiter = new DiamondMatrixIterator(0);
    private static final Vector2i diamondMatrixPos = new Vector2i();
    private static Vector3f tmpVec = new Vector3f();
    private static IsoGameCharacter.TorchInfo tmpTorch = new IsoGameCharacter.TorchInfo();
    private static ColorInfo tmpColInfo = new ColorInfo();
    private static int[] test = new int[]{0, 1, 768, 769, 774, 775, 770, 771, 772, 773, 32769, 32770, 32771, 32772, 776, 35065, 35066, 34185, 35067};
    private static String[] testNames = new String[]{
        "GL_ZERO",
        "GL_ONE",
        "GL_SRC_COLOR",
        "GL_ONE_MINUS_SRC_COLOR",
        "GL_DST_COLOR",
        "GL_ONE_MINUS_DST_COLOR",
        "GL_SRC_ALPHA",
        "GL_ONE_MINUS_SRC_ALPHA",
        "GL_DST_ALPHA",
        "GL_ONE_MINUS_DST_ALPHA",
        "GL_CONSTANT_COLOR",
        "GL_ONE_MINUS_CONSTANT_COLOR",
        "GL_CONSTANT_ALPHA",
        "GL_ONE_MINUS_CONSTANT_ALPHA",
        "GL_SRC_ALPHA_SATURATE",
        "GL_SRC1_COLOR (33)",
        "GL_ONE_MINUS_SRC1_COLOR (33)",
        "GL_SRC1_ALPHA (15)",
        "GL_ONE_MINUS_SRC1_ALPHA (33)"
    };
    private static int var1 = 1;
    private static int var2 = 1;
    private static float var3 = 1.0F;
    private static int SCR_MASK_ADD = 770;
    private static int DST_MASK_ADD = 771;
    private static int SCR_MASK_SUB = 0;
    private static int DST_MASK_SUB = 0;
    private static int SCR_PARTICLES = 1;
    private static int DST_PARTICLES = 771;
    private static int SCR_MERGE = 770;
    private static int DST_MERGE = 771;
    private static int SCR_FINAL = 770;
    private static int DST_FINAL = 771;
    private static int ID_SCR_MASK_ADD;
    private static int ID_DST_MASK_ADD;
    private static int ID_SCR_MASK_SUB;
    private static int ID_DST_MASK_SUB;
    private static int ID_SCR_MERGE;
    private static int ID_DST_MERGE;
    private static int ID_SCR_FINAL;
    private static int ID_DST_FINAL;
    private static int ID_SCR_PARTICLES;
    private static int ID_DST_PARTICLES;
    private static int TARGET_BLEND = 0;
    private static boolean DEBUG_MASK = false;
    public static boolean MASKING_ENABLED = true;
    private static boolean DEBUG_MASK_AND_PARTICLES = false;
    private static final boolean DEBUG_THROTTLE_KEYS = true;
    private static int keypause = 0;

    public static TextureFBO getFboMask() {
        return fboMask;
    }

    public static TextureFBO getFboParticles() {
        return fboParticles;
    }

    public static void init() throws Exception {
        if (!GameServer.bServer) {
            for (int _int = 0; _int < playerMasks.length; _int++) {
                playerMasks[_int] = new WeatherFxMask.PlayerFxMask();
            }

            playerMasks[0].init();
            initGlIds();
            floorSprite = IsoSpriteManager.instance.getSprite("floors_interior_tilesandwood_01_16");
            wallNSprite = IsoSpriteManager.instance.getSprite("walls_interior_house_01_21");
            wallWSprite = IsoSpriteManager.instance.getSprite("walls_interior_house_01_20");
            wallNWSprite = IsoSpriteManager.instance.getSprite("walls_interior_house_01_22");
            wallSESprite = IsoSpriteManager.instance.getSprite("walls_interior_house_01_23");
            texWhite = Texture.getSharedTexture("media/textures/weather/fogwhite.png");
        }
    }

    public static boolean checkFbos() {
        if (GameServer.bServer) {
            return false;
        } else {
            TextureFBO textureFBO = Core.getInstance().getOffscreenBuffer();
            if (Core.getInstance().getOffscreenBuffer() == null) {
                DebugLog.log("fbo=" + (textureFBO != null));
                return false;
            } else {
                int int0 = Core.getInstance().getScreenWidth();
                int int1 = Core.getInstance().getScreenHeight();
                if (fboMask != null && fboParticles != null && fboMask.getTexture().getWidth() == int0 && fboMask.getTexture().getHeight() == int1) {
                    return fboMask != null && fboParticles != null;
                } else {
                    if (fboMask != null) {
                        fboMask.destroy();
                    }

                    if (fboParticles != null) {
                        fboParticles.destroy();
                    }

                    fboMask = null;
                    fboParticles = null;

                    try {
                        Texture texture0 = new Texture(int0, int1, 16);
                        fboMask = new TextureFBO(texture0);
                    } catch (Exception exception0) {
                        DebugLog.log(exception0.getStackTrace());
                        exception0.printStackTrace();
                    }

                    try {
                        Texture texture1 = new Texture(int0, int1, 16);
                        fboParticles = new TextureFBO(texture1);
                    } catch (Exception exception1) {
                        DebugLog.log(exception1.getStackTrace());
                        exception1.printStackTrace();
                    }

                    return fboMask != null && fboParticles != null;
                }
            }
        }
    }

    public static void destroy() {
        if (fboMask != null) {
            fboMask.destroy();
        }

        fboMask = null;
        if (fboParticles != null) {
            fboParticles.destroy();
        }

        fboParticles = null;
    }

    public static void initMask() {
        if (!GameServer.bServer) {
            curPlayerIndex = IsoCamera.frameState.playerIndex;
            playerMasks[curPlayerIndex].initMask();
        }
    }

    private static boolean isOnScreen(int int0, int int1, int int2) {
        float float0 = (float)((int)IsoUtils.XToScreenInt(int0, int1, int2, 0));
        float float1 = (float)((int)IsoUtils.YToScreenInt(int0, int1, int2, 0));
        float0 -= (float)((int)IsoCamera.frameState.OffX);
        float1 -= (float)((int)IsoCamera.frameState.OffY);
        if (float0 + (float)(32 * Core.TileScale) <= 0.0F) {
            return false;
        } else if (float1 + (float)(32 * Core.TileScale) <= 0.0F) {
            return false;
        } else {
            return float0 - (float)(32 * Core.TileScale) >= (float)IsoCamera.frameState.OffscreenWidth
                ? false
                : !(float1 - (float)(96 * Core.TileScale) >= (float)IsoCamera.frameState.OffscreenHeight);
        }
    }

    public boolean isLoc(int _x, int _y, int _z) {
        return this.x == _x && this.y == _y && this.z == _z;
    }

    public static boolean playerHasMaskToDraw(int plrIndex) {
        return plrIndex < playerMasks.length ? playerMasks[plrIndex].hasMaskToDraw : false;
    }

    public static void setDiamondIterDone(int plrIndex) {
        if (plrIndex < playerMasks.length) {
            playerMasks[plrIndex].DIAMOND_ITER_DONE = true;
        }
    }

    public static void forceMaskUpdate(int plrIndex) {
        if (plrIndex < playerMasks.length) {
            playerMasks[plrIndex].plrSquare = null;
        }
    }

    public static void forceMaskUpdateAll() {
        if (!GameServer.bServer) {
            for (int _int = 0; _int < playerMasks.length; _int++) {
                playerMasks[_int].plrSquare = null;
            }
        }
    }

    private static boolean getIsStairs(IsoGridSquare isoGridSquare) {
        return isoGridSquare != null
            && (
                isoGridSquare.Has(IsoObjectType.stairsBN)
                    || isoGridSquare.Has(IsoObjectType.stairsBW)
                    || isoGridSquare.Has(IsoObjectType.stairsMN)
                    || isoGridSquare.Has(IsoObjectType.stairsMW)
                    || isoGridSquare.Has(IsoObjectType.stairsTN)
                    || isoGridSquare.Has(IsoObjectType.stairsTW)
            );
    }

    private static boolean getHasDoor(IsoGridSquare isoGridSquare) {
        return isoGridSquare != null
                && (isoGridSquare.Is(IsoFlagType.cutN) || isoGridSquare.Is(IsoFlagType.cutW))
                && (isoGridSquare.Is(IsoFlagType.DoorWallN) || isoGridSquare.Is(IsoFlagType.DoorWallW))
                && !isoGridSquare.Is(IsoFlagType.doorN)
                && !isoGridSquare.Is(IsoFlagType.doorW)
            ? isoGridSquare.getCanSee(curPlayerIndex)
            : false;
    }

    public static void addMaskLocation(IsoGridSquare _gs, int _x, int _y, int _z) {
        if (!GameServer.bServer) {
            WeatherFxMask.PlayerFxMask playerFxMask = playerMasks[curPlayerIndex];
            if (playerFxMask.requiresUpdate) {
                if (playerFxMask.hasMaskToDraw && playerFxMask.playerZ == _z) {
                    if (isInPlayerBuilding(_gs, _x, _y, _z)) {
                        IsoGridSquare isoGridSquare0 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x, _y - 1, _z);
                        boolean boolean0 = !isInPlayerBuilding(isoGridSquare0, _x, _y - 1, _z);
                        isoGridSquare0 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x - 1, _y, _z);
                        boolean boolean1 = !isInPlayerBuilding(isoGridSquare0, _x - 1, _y, _z);
                        isoGridSquare0 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x - 1, _y - 1, _z);
                        boolean boolean2 = !isInPlayerBuilding(isoGridSquare0, _x - 1, _y - 1, _z);
                        byte byte0 = 0;
                        if (boolean0) {
                            byte0 |= 1;
                        }

                        if (boolean1) {
                            byte0 |= 2;
                        }

                        if (boolean2) {
                            byte0 |= 32;
                        }

                        boolean boolean3 = false;
                        boolean boolean4 = getIsStairs(_gs);
                        if (_gs != null && (boolean0 || boolean1 || boolean2)) {
                            byte byte1 = 24;
                            if (boolean0 && !_gs.getProperties().Is(IsoFlagType.WallN) && !_gs.Is(IsoFlagType.WallNW)) {
                                playerFxMask.addMask(_x - 1, _y, _z, null, 8, false);
                                playerFxMask.addMask(_x, _y, _z, _gs, byte1);
                                playerFxMask.addMask(_x + 1, _y, _z, null, byte1, false);
                                playerFxMask.addMask(_x + 2, _y, _z, null, 8, false);
                                playerFxMask.addMask(_x, _y + 1, _z, null, 8, false);
                                playerFxMask.addMask(_x + 1, _y + 1, _z, null, byte1, false);
                                playerFxMask.addMask(_x + 2, _y + 1, _z, null, byte1, false);
                                playerFxMask.addMask(_x + 2, _y + 2, _z, null, 16, false);
                                playerFxMask.addMask(_x + 3, _y + 2, _z, null, 16, false);
                                boolean3 = true;
                            }

                            if (boolean1 && !_gs.getProperties().Is(IsoFlagType.WallW) && !_gs.getProperties().Is(IsoFlagType.WallNW)) {
                                playerFxMask.addMask(_x, _y - 1, _z, null, 8, false);
                                playerFxMask.addMask(_x, _y, _z, _gs, byte1);
                                playerFxMask.addMask(_x, _y + 1, _z, null, byte1, false);
                                playerFxMask.addMask(_x, _y + 2, _z, null, 8, false);
                                playerFxMask.addMask(_x + 1, _y, _z, null, 8, false);
                                playerFxMask.addMask(_x + 1, _y + 1, _z, null, byte1, false);
                                playerFxMask.addMask(_x + 1, _y + 2, _z, null, byte1, false);
                                playerFxMask.addMask(_x + 2, _y + 2, _z, null, 16, false);
                                playerFxMask.addMask(_x + 2, _y + 3, _z, null, 16, false);
                                boolean3 = true;
                            }

                            if (boolean2) {
                                byte byte2 = boolean4 ? byte1 : byte0;
                                playerFxMask.addMask(_x, _y, _z, _gs, byte2);
                                boolean3 = true;
                            }
                        }

                        if (!boolean3) {
                            byte byte3 = boolean4 ? 24 : byte0;
                            playerFxMask.addMask(_x, _y, _z, _gs, byte3);
                        }
                    } else {
                        IsoGridSquare isoGridSquare1 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x, _y - 1, _z);
                        boolean boolean5 = isInPlayerBuilding(isoGridSquare1, _x, _y - 1, _z);
                        isoGridSquare1 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x - 1, _y, _z);
                        boolean boolean6 = isInPlayerBuilding(isoGridSquare1, _x - 1, _y, _z);
                        if (!boolean5 && !boolean6) {
                            isoGridSquare1 = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(_x - 1, _y - 1, _z);
                            if (isInPlayerBuilding(isoGridSquare1, _x - 1, _y - 1, _z)) {
                                playerFxMask.addMask(_x, _y, _z, _gs, 4);
                            }
                        } else {
                            byte byte4 = 4;
                            if (boolean5) {
                                byte4 |= 1;
                            }

                            if (boolean6) {
                                byte4 |= 2;
                            }

                            if (getHasDoor(_gs)) {
                                byte4 |= 64;
                            }

                            playerFxMask.addMask(_x, _y, _z, _gs, byte4);
                        }
                    }
                }
            }
        }
    }

    private static boolean isInPlayerBuilding(IsoGridSquare isoGridSquare, int int0, int int1, int int2) {
        WeatherFxMask.PlayerFxMask playerFxMask = playerMasks[curPlayerIndex];
        if (isoGridSquare != null && isoGridSquare.Is(IsoFlagType.solidfloor)) {
            if (isoGridSquare.getBuilding() != null && isoGridSquare.getBuilding() == playerFxMask.player.getBuilding()) {
                return true;
            }

            if (isoGridSquare.getBuilding() == null) {
                return playerFxMask.curIsoWorldRegion != null
                    && isoGridSquare.getIsoWorldRegion() != null
                    && isoGridSquare.getIsoWorldRegion().isFogMask()
                    && (
                        isoGridSquare.getIsoWorldRegion() == playerFxMask.curIsoWorldRegion
                            || playerFxMask.curConnectedRegions.contains(isoGridSquare.getIsoWorldRegion())
                    );
            }
        } else {
            if (isInteriorLocation(int0, int1, int2)) {
                return true;
            }

            if (isoGridSquare != null && isoGridSquare.getBuilding() == null) {
                return playerFxMask.curIsoWorldRegion != null
                    && isoGridSquare.getIsoWorldRegion() != null
                    && isoGridSquare.getIsoWorldRegion().isFogMask()
                    && (
                        isoGridSquare.getIsoWorldRegion() == playerFxMask.curIsoWorldRegion
                            || playerFxMask.curConnectedRegions.contains(isoGridSquare.getIsoWorldRegion())
                    );
            }

            if (isoGridSquare == null && playerFxMask.curIsoWorldRegion != null) {
                IWorldRegion iWorldRegion = IsoRegions.getIsoWorldRegion(int0, int1, int2);
                return iWorldRegion != null
                    && iWorldRegion.isFogMask()
                    && (iWorldRegion == playerFxMask.curIsoWorldRegion || playerFxMask.curConnectedRegions.contains(iWorldRegion));
            }
        }

        return false;
    }

    private static boolean isInteriorLocation(int int2, int int3, int int1) {
        WeatherFxMask.PlayerFxMask playerFxMask = playerMasks[curPlayerIndex];

        for (int int0 = int1; int0 >= 0; int0--) {
            IsoGridSquare isoGridSquare = IsoWorld.instance.getCell().getChunkMap(curPlayerIndex).getGridSquare(int2, int3, int0);
            if (isoGridSquare != null) {
                if (isoGridSquare.getBuilding() != null && isoGridSquare.getBuilding() == playerFxMask.player.getBuilding()) {
                    return true;
                }

                if (isoGridSquare.Is(IsoFlagType.exterior)) {
                    return false;
                }
            }
        }

        return false;
    }

    private static void scanForTiles(int int0) {
        WeatherFxMask.PlayerFxMask playerFxMask = playerMasks[curPlayerIndex];
        if (!playerFxMask.DIAMOND_ITER_DONE) {
            IsoPlayer isoPlayer = IsoPlayer.players[int0];
            int int1 = (int)isoPlayer.getZ();
            byte byte0 = 0;
            byte byte1 = 0;
            int int2 = byte0 + IsoCamera.getOffscreenWidth(int0);
            int int3 = byte1 + IsoCamera.getOffscreenHeight(int0);
            float float0 = IsoUtils.XToIso((float)byte0, (float)byte1, 0.0F);
            float float1 = IsoUtils.YToIso((float)int2, (float)byte1, 0.0F);
            float float2 = IsoUtils.XToIso((float)int2, (float)int3, 6.0F);
            float float3 = IsoUtils.YToIso((float)byte0, (float)int3, 6.0F);
            float float4 = IsoUtils.XToIso((float)int2, (float)byte1, 0.0F);
            int int4 = (int)float1;
            int int5 = (int)float3;
            int int6 = (int)float0;
            int int7 = (int)float2;
            DIAMOND_ROWS = (int)float4 * 4;
            int6 -= 2;
            int4 -= 2;
            dmiter.reset(int7 - int6);
            Vector2i vector2i = diamondMatrixPos;
            IsoChunkMap isoChunkMap = IsoWorld.instance.getCell().getChunkMap(int0);

            while (dmiter.next(vector2i)) {
                if (vector2i != null) {
                    IsoGridSquare isoGridSquare = isoChunkMap.getGridSquare(vector2i.x + int6, vector2i.y + int4, int1);
                    if (isoGridSquare == null) {
                        addMaskLocation(null, vector2i.x + int6, vector2i.y + int4, int1);
                    } else {
                        IsoChunk isoChunk = isoGridSquare.getChunk();
                        if (isoChunk != null && isoGridSquare.IsOnScreen()) {
                            addMaskLocation(isoGridSquare, vector2i.x + int6, vector2i.y + int4, int1);
                        }
                    }
                }
            }
        }
    }

    private static void renderMaskFloor(int int2, int int1, int int0) {
        floorSprite.render(null, (float)int2, (float)int1, (float)int0, IsoDirections.N, offsetX, offsetY, defColorInfo, false);
    }

    private static void renderMaskWall(IsoGridSquare isoGridSquare0, int var1x, int var2x, int var3x, boolean boolean3, boolean boolean4, int _int) {
        if (isoGridSquare0 != null) {
            IsoGridSquare isoGridSquare1 = isoGridSquare0.nav[IsoDirections.S.index()];
            IsoGridSquare isoGridSquare2 = isoGridSquare0.nav[IsoDirections.E.index()];
            long _long = System.currentTimeMillis();
            boolean boolean0 = isoGridSquare1 != null && isoGridSquare1.getPlayerCutawayFlag(_int, _long);
            boolean boolean1 = isoGridSquare0.getPlayerCutawayFlag(_int, _long);
            boolean boolean2 = isoGridSquare2 != null && isoGridSquare2.getPlayerCutawayFlag(_int, _long);
            IsoSprite isoSprite;
            IsoDirections isoDirections;
            if (boolean3 && boolean4) {
                isoSprite = wallNWSprite;
                isoDirections = IsoDirections.NW;
            } else if (boolean3) {
                isoSprite = wallNSprite;
                isoDirections = IsoDirections.N;
            } else if (boolean4) {
                isoSprite = wallWSprite;
                isoDirections = IsoDirections.W;
            } else {
                isoSprite = wallSESprite;
                isoDirections = IsoDirections.W;
            }

            isoGridSquare0.DoCutawayShaderSprite(isoSprite, isoDirections, boolean0, boolean1, boolean2);
        }
    }

    private static void renderMaskWallNoCuts(int int2, int int1, int int0, boolean boolean0, boolean boolean1) {
        if (boolean0 && boolean1) {
            wallNWSprite.render(null, (float)int2, (float)int1, (float)int0, IsoDirections.N, offsetX, offsetY, defColorInfo, false);
        } else if (boolean0) {
            wallNSprite.render(null, (float)int2, (float)int1, (float)int0, IsoDirections.N, offsetX, offsetY, defColorInfo, false);
        } else if (boolean1) {
            wallWSprite.render(null, (float)int2, (float)int1, (float)int0, IsoDirections.N, offsetX, offsetY, defColorInfo, false);
        } else {
            wallSESprite.render(null, (float)int2, (float)int1, (float)int0, IsoDirections.N, offsetX, offsetY, defColorInfo, false);
        }
    }

    public static void renderFxMask(int nPlayer) {
        if (DebugOptions.instance.Weather.Fx.getValue()) {
            if (!GameServer.bServer) {
                if (IsoWeatherFX.instance != null) {
                    if (LuaManager.thread == null || !LuaManager.thread.bStep) {
                        if (DEBUG_KEYS && Core.bDebug) {
                            updateDebugKeys();
                        }

                        if (playerMasks[nPlayer].maskEnabled) {
                            WeatherFxMask.PlayerFxMask playerFxMask = playerMasks[curPlayerIndex];
                            if (playerFxMask.maskEnabled) {
                                if (MASKING_ENABLED && !checkFbos()) {
                                    MASKING_ENABLED = false;
                                }

                                if (MASKING_ENABLED && playerFxMask.hasMaskToDraw) {
                                    scanForTiles(nPlayer);
                                    int int0 = IsoCamera.getOffscreenLeft(nPlayer);
                                    int int1 = IsoCamera.getOffscreenTop(nPlayer);
                                    int int2 = IsoCamera.getOffscreenWidth(nPlayer);
                                    int int3 = IsoCamera.getOffscreenHeight(nPlayer);
                                    int int4 = IsoCamera.getScreenWidth(nPlayer);
                                    int int5 = IsoCamera.getScreenHeight(nPlayer);
                                    SpriteRenderer.instance.glIgnoreStyles(true);
                                    if (MASKING_ENABLED) {
                                        SpriteRenderer.instance.glBuffer(4, nPlayer);
                                        SpriteRenderer.instance.glDoStartFrameFx(int2, int3, nPlayer);
                                        if (PerformanceSettings.LightingFrameSkip < 3) {
                                            IsoWorld.instance.getCell().DrawStencilMask();
                                            SpriteRenderer.instance.glClearColor(0, 0, 0, 0);
                                            SpriteRenderer.instance.glClear(16640);
                                            SpriteRenderer.instance.glClearColor(0, 0, 0, 255);
                                        }

                                        boolean boolean0 = true;
                                        boolean boolean1 = false;
                                        WeatherFxMask[] weatherFxMask0 = playerMasks[nPlayer].masks;
                                        int int6 = playerMasks[nPlayer].maskPointer;

                                        for (int int7 = 0; int7 < int6; int7++) {
                                            WeatherFxMask weatherFxMask1 = weatherFxMask0[int7];
                                            if (weatherFxMask1.enabled) {
                                                if ((weatherFxMask1.flags & 4) == 4) {
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                                    SpriteRenderer.instance.glBlendFunc(SCR_MASK_SUB, DST_MASK_SUB);
                                                    SpriteRenderer.instance.glBlendEquation(32779);
                                                    zombie.IndieGL.enableAlphaTest();
                                                    zombie.IndieGL.glAlphaFunc(516, 0.02F);
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
                                                    boolean boolean2 = (weatherFxMask1.flags & 1) == 1;
                                                    boolean boolean3 = (weatherFxMask1.flags & 2) == 2;
                                                    renderMaskWall(
                                                        weatherFxMask1.gs, weatherFxMask1.x, weatherFxMask1.y, weatherFxMask1.z, boolean2, boolean3, nPlayer
                                                    );
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                                    SpriteRenderer.instance.glBlendEquation(32774);
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
                                                    boolean boolean4 = (weatherFxMask1.flags & 64) == 64;
                                                    if (boolean4 && weatherFxMask1.gs != null) {
                                                        SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                                        SpriteRenderer.instance.glBlendFunc(SCR_MASK_ADD, DST_MASK_ADD);
                                                        SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
                                                        weatherFxMask1.gs.RenderOpenDoorOnly();
                                                    }
                                                } else {
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                                    SpriteRenderer.instance.glBlendFunc(SCR_MASK_ADD, DST_MASK_ADD);
                                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
                                                    renderMaskFloor(weatherFxMask1.x, weatherFxMask1.y, weatherFxMask1.z);
                                                    boolean1 = (weatherFxMask1.flags & 16) == 16;
                                                    boolean boolean5 = (weatherFxMask1.flags & 8) == 8;
                                                    if (!boolean1) {
                                                        boolean boolean6 = (weatherFxMask1.flags & 1) == 1;
                                                        boolean boolean7 = (weatherFxMask1.flags & 2) == 2;
                                                        if (!boolean6 && !boolean7) {
                                                            if ((weatherFxMask1.flags & 32) == 32) {
                                                                renderMaskWall(
                                                                    weatherFxMask1.gs,
                                                                    weatherFxMask1.x,
                                                                    weatherFxMask1.y,
                                                                    weatherFxMask1.z,
                                                                    false,
                                                                    false,
                                                                    nPlayer
                                                                );
                                                            }
                                                        } else {
                                                            renderMaskWall(
                                                                weatherFxMask1.gs,
                                                                weatherFxMask1.x,
                                                                weatherFxMask1.y,
                                                                weatherFxMask1.z,
                                                                boolean6,
                                                                boolean7,
                                                                nPlayer
                                                            );
                                                        }
                                                    }

                                                    if (boolean1 && weatherFxMask1.gs != null) {
                                                        weatherFxMask1.gs.RenderMinusFloorFxMask(weatherFxMask1.z + 1, false, false);
                                                    }

                                                    if (boolean5 && weatherFxMask1.gs != null) {
                                                        weatherFxMask1.gs.renderCharacters(weatherFxMask1.z + 1, false, false);
                                                        SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                                        SpriteRenderer.instance.glBlendFunc(SCR_MASK_ADD, DST_MASK_ADD);
                                                        SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
                                                    }
                                                }
                                            }
                                        }

                                        SpriteRenderer.instance.glBlendFunc(770, 771);
                                        SpriteRenderer.instance.glBuffer(5, nPlayer);
                                        SpriteRenderer.instance.glDoEndFrameFx(nPlayer);
                                    }

                                    if (DEBUG_MASK_AND_PARTICLES) {
                                        SpriteRenderer.instance.glClearColor(0, 0, 0, 255);
                                        SpriteRenderer.instance.glClear(16640);
                                        SpriteRenderer.instance.glClearColor(0, 0, 0, 255);
                                    } else if (DEBUG_MASK) {
                                        SpriteRenderer.instance.glClearColor(0, 255, 0, 255);
                                        SpriteRenderer.instance.glClear(16640);
                                        SpriteRenderer.instance.glClearColor(0, 0, 0, 255);
                                    }

                                    if (!RenderSettings.getInstance().getPlayerSettings(nPlayer).isExterior()) {
                                        drawFxLayered(nPlayer, false, false, false);
                                    }

                                    if (IsoWeatherFX.instance.hasCloudsToRender()) {
                                        drawFxLayered(nPlayer, true, false, false);
                                    }

                                    if (IsoWeatherFX.instance.hasFogToRender() && PerformanceSettings.FogQuality == 2) {
                                        drawFxLayered(nPlayer, false, true, false);
                                    }

                                    if (Core.OptionRenderPrecipitation == 1 && IsoWeatherFX.instance.hasPrecipitationToRender()) {
                                        drawFxLayered(nPlayer, false, false, true);
                                    }

                                    SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
                                    SpriteRenderer.instance.glIgnoreStyles(false);
                                } else {
                                    if (IsoWorld.instance.getCell() != null && IsoWorld.instance.getCell().getWeatherFX() != null) {
                                        SpriteRenderer.instance.glIgnoreStyles(true);
                                        SpriteRenderer.instance.glBlendFunc(770, 771);
                                        IsoWorld.instance.getCell().getWeatherFX().render();
                                        SpriteRenderer.instance.glIgnoreStyles(false);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private static void drawFxLayered(int int1, boolean boolean2, boolean boolean1, boolean boolean0) {
        int int0 = IsoCamera.getOffscreenLeft(int1);
        int int2 = IsoCamera.getOffscreenTop(int1);
        int int3 = IsoCamera.getOffscreenWidth(int1);
        int int4 = IsoCamera.getOffscreenHeight(int1);
        int int5 = IsoCamera.getScreenLeft(int1);
        int int6 = IsoCamera.getScreenTop(int1);
        int int7 = IsoCamera.getScreenWidth(int1);
        int int8 = IsoCamera.getScreenHeight(int1);
        SpriteRenderer.instance.glBuffer(6, int1);
        SpriteRenderer.instance.glDoStartFrameFx(int3, int4, int1);
        if (!boolean2 && !boolean1 && !boolean0) {
            Color color = RenderSettings.getInstance().getMaskClearColorForPlayer(int1);
            SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
            SpriteRenderer.instance.glBlendFuncSeparate(SCR_PARTICLES, DST_PARTICLES, 1, 771);
            SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
            SpriteRenderer.instance.renderi(texWhite, 0, 0, int3, int4, color.r, color.g, color.b, color.a, null);
            SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
        } else if (IsoWorld.instance.getCell() != null && IsoWorld.instance.getCell().getWeatherFX() != null) {
            SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
            SpriteRenderer.instance.glBlendFuncSeparate(SCR_PARTICLES, DST_PARTICLES, 1, 771);
            SpriteRenderer.GL_BLENDFUNC_ENABLED = false;
            IsoWorld.instance.getCell().getWeatherFX().renderLayered(boolean2, boolean1, boolean0);
            SpriteRenderer.GL_BLENDFUNC_ENABLED = true;
        }

        if (MASKING_ENABLED) {
            SpriteRenderer.instance.glBlendFunc(SCR_MERGE, DST_MERGE);
            SpriteRenderer.instance.glBlendEquation(32779);
            ((Texture)fboMask.getTexture()).rendershader2(0.0F, 0.0F, (float)int3, (float)int4, int5, int6, int7, int8, 1.0F, 1.0F, 1.0F, 1.0F);
            SpriteRenderer.instance.glBlendEquation(32774);
        }

        SpriteRenderer.instance.glBlendFunc(770, 771);
        SpriteRenderer.instance.glBuffer(7, int1);
        SpriteRenderer.instance.glDoEndFrameFx(int1);
        Texture texture;
        if ((DEBUG_MASK || DEBUG_MASK_AND_PARTICLES) && !DEBUG_MASK_AND_PARTICLES) {
            texture = (Texture)fboMask.getTexture();
            SpriteRenderer.instance.glBlendFunc(770, 771);
        } else {
            texture = (Texture)fboParticles.getTexture();
            SpriteRenderer.instance.glBlendFunc(SCR_FINAL, DST_FINAL);
        }

        float float0 = 1.0F;
        float float1 = 1.0F;
        float float2 = 1.0F;
        float float3 = 1.0F;
        float float4 = (float)int5 / (float)texture.getWidthHW();
        float float5 = (float)int6 / (float)texture.getHeightHW();
        float float6 = (float)(int5 + int7) / (float)texture.getWidthHW();
        float float7 = (float)(int6 + int8) / (float)texture.getHeightHW();
        SpriteRenderer.instance
            .render(
                texture, 0.0F, 0.0F, (float)int3, (float)int4, float0, float1, float2, float3, float4, float7, float6, float7, float6, float5, float4, float5
            );
    }

    private static void initGlIds() {
        for (int _int = 0; _int < test.length; _int++) {
            if (test[_int] == SCR_MASK_ADD) {
                ID_SCR_MASK_ADD = _int;
            } else if (test[_int] == DST_MASK_ADD) {
                ID_DST_MASK_ADD = _int;
            } else if (test[_int] == SCR_MASK_SUB) {
                ID_SCR_MASK_SUB = _int;
            } else if (test[_int] == DST_MASK_SUB) {
                ID_DST_MASK_SUB = _int;
            } else if (test[_int] == SCR_PARTICLES) {
                ID_SCR_PARTICLES = _int;
            } else if (test[_int] == DST_PARTICLES) {
                ID_DST_PARTICLES = _int;
            } else if (test[_int] == SCR_MERGE) {
                ID_SCR_MERGE = _int;
            } else if (test[_int] == DST_MERGE) {
                ID_DST_MERGE = _int;
            } else if (test[_int] == SCR_FINAL) {
                ID_SCR_FINAL = _int;
            } else if (test[_int] == DST_FINAL) {
                ID_DST_FINAL = _int;
            }
        }
    }

    private static void updateDebugKeys() {
        if (keypause > 0) {
            keypause--;
        }

        if (keypause == 0) {
            boolean boolean0 = false;
            boolean boolean1 = false;
            boolean boolean2 = false;
            boolean boolean3 = false;
            boolean boolean4 = false;
            if (TARGET_BLEND == 0) {
                var1 = ID_SCR_MASK_ADD;
                var2 = ID_DST_MASK_ADD;
            } else if (TARGET_BLEND == 1) {
                var1 = ID_SCR_MASK_SUB;
                var2 = ID_DST_MASK_SUB;
            } else if (TARGET_BLEND == 2) {
                var1 = ID_SCR_MERGE;
                var2 = ID_DST_MERGE;
            } else if (TARGET_BLEND == 3) {
                var1 = ID_SCR_FINAL;
                var2 = ID_DST_FINAL;
            } else if (TARGET_BLEND == 4) {
                var1 = ID_SCR_PARTICLES;
                var2 = ID_DST_PARTICLES;
            }

            if (GameKeyboard.isKeyDown(79)) {
                var1--;
                if (var1 < 0) {
                    var1 = test.length - 1;
                }

                boolean0 = true;
            } else if (GameKeyboard.isKeyDown(81)) {
                var1++;
                if (var1 >= test.length) {
                    var1 = 0;
                }

                boolean0 = true;
            } else if (GameKeyboard.isKeyDown(75)) {
                var2--;
                if (var2 < 0) {
                    var2 = test.length - 1;
                }

                boolean0 = true;
            } else if (GameKeyboard.isKeyDown(77)) {
                var2++;
                if (var2 >= test.length) {
                    var2 = 0;
                }

                boolean0 = true;
            } else if (GameKeyboard.isKeyDown(71)) {
                TARGET_BLEND--;
                if (TARGET_BLEND < 0) {
                    TARGET_BLEND = 4;
                }

                boolean0 = true;
                boolean1 = true;
            } else if (GameKeyboard.isKeyDown(73)) {
                TARGET_BLEND++;
                if (TARGET_BLEND >= 5) {
                    TARGET_BLEND = 0;
                }

                boolean0 = true;
                boolean1 = true;
            } else if (MASKING_ENABLED && GameKeyboard.isKeyDown(82)) {
                DEBUG_MASK = !DEBUG_MASK;
                boolean0 = true;
                boolean2 = true;
            } else if (MASKING_ENABLED && GameKeyboard.isKeyDown(80)) {
                DEBUG_MASK_AND_PARTICLES = !DEBUG_MASK_AND_PARTICLES;
                boolean0 = true;
                boolean3 = true;
            } else if (!GameKeyboard.isKeyDown(72) && GameKeyboard.isKeyDown(76)) {
                MASKING_ENABLED = !MASKING_ENABLED;
                boolean0 = true;
                boolean4 = true;
            }

            if (boolean0) {
                if (boolean1) {
                    if (TARGET_BLEND == 0) {
                        DebugLog.log("TargetBlend = MASK_ADD");
                    } else if (TARGET_BLEND == 1) {
                        DebugLog.log("TargetBlend = MASK_SUB");
                    } else if (TARGET_BLEND == 2) {
                        DebugLog.log("TargetBlend = MERGE");
                    } else if (TARGET_BLEND == 3) {
                        DebugLog.log("TargetBlend = FINAL");
                    } else if (TARGET_BLEND == 4) {
                        DebugLog.log("TargetBlend = PARTICLES");
                    }
                } else if (boolean2) {
                    DebugLog.log("DEBUG_MASK = " + DEBUG_MASK);
                } else if (boolean3) {
                    DebugLog.log("DEBUG_MASK_AND_PARTICLES = " + DEBUG_MASK_AND_PARTICLES);
                } else if (boolean4) {
                    DebugLog.log("MASKING_ENABLED = " + MASKING_ENABLED);
                } else {
                    if (TARGET_BLEND == 0) {
                        ID_SCR_MASK_ADD = var1;
                        ID_DST_MASK_ADD = var2;
                        SCR_MASK_ADD = test[ID_SCR_MASK_ADD];
                        DST_MASK_ADD = test[ID_DST_MASK_ADD];
                    } else if (TARGET_BLEND == 1) {
                        ID_SCR_MASK_SUB = var1;
                        ID_DST_MASK_SUB = var2;
                        SCR_MASK_SUB = test[ID_SCR_MASK_SUB];
                        DST_MASK_SUB = test[ID_DST_MASK_SUB];
                    } else if (TARGET_BLEND == 2) {
                        ID_SCR_MERGE = var1;
                        ID_DST_MERGE = var2;
                        SCR_MERGE = test[ID_SCR_MERGE];
                        DST_MERGE = test[ID_DST_MERGE];
                    } else if (TARGET_BLEND == 3) {
                        ID_SCR_FINAL = var1;
                        ID_DST_FINAL = var2;
                        SCR_FINAL = test[ID_SCR_FINAL];
                        DST_FINAL = test[ID_DST_FINAL];
                    } else if (TARGET_BLEND == 4) {
                        ID_SCR_PARTICLES = var1;
                        ID_DST_PARTICLES = var2;
                        SCR_PARTICLES = test[ID_SCR_PARTICLES];
                        DST_PARTICLES = test[ID_DST_PARTICLES];
                    }

                    DebugLog.log("Blendmode = " + testNames[var1] + " -> " + testNames[var2]);
                }

                keypause = 30;
            }
        }
    }

    public static class PlayerFxMask {
        private WeatherFxMask[] masks;
        private int maskPointer = 0;
        private boolean maskEnabled = false;
        private IsoGridSquare plrSquare;
        private int DISABLED_MASKS = 0;
        private boolean requiresUpdate = false;
        private boolean hasMaskToDraw = true;
        private int playerIndex;
        private IsoPlayer player;
        private int playerZ;
        private IWorldRegion curIsoWorldRegion;
        private ArrayList<IWorldRegion> curConnectedRegions = new ArrayList();
        private final ArrayList<IWorldRegion> isoWorldRegionTemp = new ArrayList();
        private boolean DIAMOND_ITER_DONE = false;
        private boolean isFirstSquare = true;
        private IsoGridSquare firstSquare;

        private void init() {
            this.masks = new WeatherFxMask[30000];

            for (int _int = 0; _int < this.masks.length; _int++) {
                if (this.masks[_int] == null) {
                    this.masks[_int] = new WeatherFxMask();
                }
            }

            this.maskEnabled = true;
        }

        private void initMask() {
            if (!GameServer.bServer) {
                if (!this.maskEnabled) {
                    this.init();
                }

                this.playerIndex = IsoCamera.frameState.playerIndex;
                this.player = IsoPlayer.players[this.playerIndex];
                this.playerZ = (int)this.player.getZ();
                this.DIAMOND_ITER_DONE = false;
                this.requiresUpdate = false;
                if (this.player != null) {
                    if (this.isFirstSquare || this.plrSquare == null || this.plrSquare != this.player.getSquare()) {
                        this.plrSquare = this.player.getSquare();
                        this.maskPointer = 0;
                        this.DISABLED_MASKS = 0;
                        this.requiresUpdate = true;
                        if (this.firstSquare == null) {
                            this.firstSquare = this.plrSquare;
                        }

                        if (this.firstSquare != null && this.firstSquare != this.plrSquare) {
                            this.isFirstSquare = false;
                        }
                    }

                    this.curIsoWorldRegion = this.player.getMasterRegion();
                    this.curConnectedRegions.clear();
                    if (this.curIsoWorldRegion != null && this.player.getMasterRegion().isFogMask()) {
                        this.isoWorldRegionTemp.clear();
                        this.isoWorldRegionTemp.add(this.curIsoWorldRegion);

                        while (this.isoWorldRegionTemp.size() > 0) {
                            IWorldRegion iWorldRegion = (IWorldRegion)this.isoWorldRegionTemp.remove(0);
                            this.curConnectedRegions.add(iWorldRegion);
                            if (iWorldRegion.getNeighbors().size() != 0) {
                                for (IsoWorldRegion isoWorldRegion : iWorldRegion.getNeighbors()) {
                                    if (!this.isoWorldRegionTemp.contains(isoWorldRegion)
                                        && !this.curConnectedRegions.contains(isoWorldRegion)
                                        && isoWorldRegion.isFogMask()) {
                                        this.isoWorldRegionTemp.add(isoWorldRegion);
                                    }
                                }
                            }
                        }
                    } else {
                        this.curIsoWorldRegion = null;
                    }
                }

                if (IsoWeatherFX.instance == null) {
                    this.hasMaskToDraw = false;
                } else {
                    this.hasMaskToDraw = true;
                    if (this.hasMaskToDraw) {
                        if ((
                                this.player.getSquare() == null
                                    || this.player.getSquare().getBuilding() == null && this.player.getSquare().Is(IsoFlagType.exterior)
                            )
                            && (this.curIsoWorldRegion == null || !this.curIsoWorldRegion.isFogMask())) {
                            this.hasMaskToDraw = false;
                        } else {
                            this.hasMaskToDraw = true;
                        }
                    }
                }
            }
        }

        private void addMask(int int0, int int1, int int2, IsoGridSquare isoGridSquare, int int3) {
            this.addMask(int0, int1, int2, isoGridSquare, int3, true);
        }

        private void addMask(int int0, int int1, int int2, IsoGridSquare isoGridSquare, int int3, boolean _boolean) {
            if (this.hasMaskToDraw && this.requiresUpdate) {
                if (!this.maskEnabled) {
                    this.init();
                }

                WeatherFxMask weatherFxMask0 = this.getMask(int0, int1, int2);
                if (weatherFxMask0 == null) {
                    WeatherFxMask weatherFxMask1 = this.getFreeMask();
                    weatherFxMask1.x = int0;
                    weatherFxMask1.y = int1;
                    weatherFxMask1.z = int2;
                    weatherFxMask1.flags = int3;
                    weatherFxMask1.gs = isoGridSquare;
                    weatherFxMask1.enabled = _boolean;
                    if (!_boolean && this.DISABLED_MASKS < WeatherFxMask.DIAMOND_ROWS) {
                        this.DISABLED_MASKS++;
                    }
                } else {
                    if (weatherFxMask0.flags != int3) {
                        weatherFxMask0.flags |= int3;
                    }

                    if (!weatherFxMask0.enabled && _boolean) {
                        WeatherFxMask weatherFxMask2 = this.getFreeMask();
                        weatherFxMask2.x = int0;
                        weatherFxMask2.y = int1;
                        weatherFxMask2.z = int2;
                        weatherFxMask2.flags = weatherFxMask0.flags;
                        weatherFxMask2.gs = isoGridSquare;
                        weatherFxMask2.enabled = _boolean;
                    } else {
                        weatherFxMask0.enabled = weatherFxMask0.enabled ? weatherFxMask0.enabled : _boolean;
                        if (_boolean && isoGridSquare != null && weatherFxMask0.gs == null) {
                            weatherFxMask0.gs = isoGridSquare;
                        }
                    }
                }
            }
        }

        private WeatherFxMask getFreeMask() {
            if (this.maskPointer >= this.masks.length) {
                DebugLog.log("Weather Mask buffer out of bounds. Increasing cache.");
                WeatherFxMask[] weatherFxMask = this.masks;
                this.masks = new WeatherFxMask[this.masks.length + 10000];

                for (int _int = 0; _int < this.masks.length; _int++) {
                    if (weatherFxMask[_int] != null) {
                        this.masks[_int] = weatherFxMask[_int];
                    } else {
                        this.masks[_int] = new WeatherFxMask();
                    }
                }
            }

            return this.masks[this.maskPointer++];
        }

        private boolean masksContains(int int0, int int1, int int2) {
            return this.getMask(int0, int1, int2) != null;
        }

        private WeatherFxMask getMask(int int2, int int3, int int4) {
            if (this.maskPointer <= 0) {
                return null;
            } else {
                int int0 = this.maskPointer - 1 - (WeatherFxMask.DIAMOND_ROWS + this.DISABLED_MASKS);
                if (int0 < 0) {
                    int0 = 0;
                }

                for (int int1 = this.maskPointer - 1; int1 >= int0; int1--) {
                    if (this.masks[int1].isLoc(int2, int3, int4)) {
                        return this.masks[int1];
                    }
                }

                return null;
            }
        }
    }
}
